
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-12-08     Wangjiangbo       the first version
 */

#include "app_comm.h"
#include "cJSON.h"
#include "app_io.h"

#define DBG_TAG "comm"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>


typedef struct {
    uint16_t cmd;

    uint8_t beep_st;
    uint8_t beep_freq;

    uint8_t status[6];


} json_req;

typedef struct {

    uint16_t cmd;
    uint16_t error;

    uint8_t sensor[2];
    uint8_t step[7];
    uint8_t eng[6];
    uint8_t emg;

} json_rep;

static bool _req_to_jsong(json_rep* rep, char* json_string, int max_len)
{
    cJSON *cmd = cJSON_CreateNumber(rep->cmd);
    cJSON *err = cJSON_CreateNumber(rep->error);

    cJSON *step = cJSON_CreateArray();
    for(int8_t i=0;i<7;i++)cJSON_AddItemToArray(step, cJSON_CreateNumber(rep->step[i]));

    cJSON *sensor = cJSON_CreateArray();
    for(int8_t i=0;i<2;i++)cJSON_AddItemToArray(sensor, cJSON_CreateNumber(rep->sensor[i]));

    cJSON *eng = cJSON_CreateArray();
    for(int8_t i=0;i<6;i++)cJSON_AddItemToArray(eng, cJSON_CreateNumber(rep->eng[i]));

    cJSON *emg = cJSON_CreateNumber(rep->emg);

    cJSON *root = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "cmd", cmd);
    cJSON_AddItemToObject(root, "err", err);
    cJSON_AddItemToObject(root, "step", step);
    cJSON_AddItemToObject(root, "sensor", sensor);
    cJSON_AddItemToObject(root, "eng", eng);
    cJSON_AddItemToObject(root, "emg", emg);

    cJSON_PrintPreallocated(root, json_string, max_len, 1);

    LOG_D("json_rep = \n%s", json_string);
    cJSON_Delete(root);
    return true;
}
//请求发送处理
void app_rep_process(char* json_rep_buff, int json_rep_buff_max_len)
{
    json_rep rep = {0};
    iomap io;
    app_io_get_gpio_map(&io);

    rep.cmd = 0;
    rep.error = 0;
    memcpy(&rep.step,&io.foot_st,7);
    memcpy(&rep.sensor,&io.sensor_st,2);
    memcpy(&rep.eng,&io.eng_trg_st,6);

    rep.emg = io.motor_stop_st ;

    _req_to_jsong(&rep, json_rep_buff, json_rep_buff_max_len);
}


static bool _json_to_req(char* json_string, json_req* req)
{
    int len = strlen(json_string);

    if(len > 1024 || json_string == NULL)
        return false;

    cJSON *root = cJSON_Parse(json_string);
    cJSON *cmd = cJSON_GetObjectItem(root, "cmd");
    cJSON *beep_st = cJSON_GetObjectItem(root, "beep");
    cJSON *beep_freq = cJSON_GetObjectItem(root, "beep_freq");
    cJSON *status = cJSON_GetObjectItem(root, "status");

    req->beep_st = cJSON_GetNumberValue(beep_st);
    req->beep_freq = cJSON_GetNumberValue(beep_freq);

    for(int i = 0; i < 6; i++)
    {
        cJSON *d = cJSON_GetArrayItem(status, i);
        req->status[i] = cJSON_GetNumberValue(d);
    }

    LOG_D("json_req = \n%s", cJSON_Print(root));

    cJSON_Delete(root);
    return true;
}


void app_comm_process(char* json_req_string, char* json_rep_buff, int json_rep_buff_max_len)
{
    json_req req = {0};
    json_rep rep = {0};

    iomap io={0};

    app_io_get_gpio_map(&io);

    rep.cmd = req.cmd + 0x8000;
    rep.error = 0;
    memcpy(&rep.step,&io.foot_st,7);
    memcpy(&rep.sensor,&io.sensor_st,2);
    memcpy(&rep.eng,&io.eng_trg_st,6);
    rep.emg = io.motor_stop_st ;

    _json_to_req(json_req_string, &req);
    memcpy(&io.eng_trg_st,&req.status,6);
    app_io_set_gpio_map(&io);


    _req_to_jsong(&rep, json_rep_buff, json_rep_buff_max_len);
}


#if 0


[D/comm] json_req =
{
    "cmd":  1,                          //命令
    "fan":  1,                          //风扇
    "rgbs": [                           //rgb灯 一共两个
        {
            "style": 1,                 //0x4 红灯 0x2绿灯 0x1蓝灯  0x7 rgb全亮白等
            "freq": 2                   //闪烁评率 0 = 不闪 100 = 100hz闪烁
        },
        {
            "style": 3,
            "freq": 4
        }
    ]
}
[D/comm] json_rep =
{
    "cmd":  32769,                      //命令返回 1 | 0x8000
    "hall": {                           //霍尔传感器
        "arm":  0,                      //器械结合
        "shell": 0,                     //无菌罩结合
        "trocar": 0                     //戳卡结合
    },
    "key":  {
        "drag": 0,                      //动力盒 拖动按键
        "err_out":      0,              //动力盒 故障退出按键
        "drag_rcm_local": 0,            //RCM臂  位置拖动
        "drag_rcm_attitude":0,          //RCM臂  姿态拖动
        "en":   0,                      //RCM臂拖动备选方案 使用按键调整位置 使能
        "up":   0,                      //RCM臂拖动备选方案  上
        "down": 0,                      //RCM臂拖动备选方案  下
        "left": 0,                      //RCM臂拖动备选方案  左
        "right": 0                      //RCM臂拖动备选方案  右
    },
    "sensor":       {
        "top":  0,                      //RCM限位传感器 上
        "bottom": 0,                    //RCM限位传感器 下
        "left": 0,                      //RCM限位传感器 左
        "right": 0                      //RCM限位传感器 右
    }
}


#endif

